using System;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Data;
using System.Data.SqlClient;

using System.Windows.Forms;

namespace YT.Controls
{
    public partial class DataGridCom : System.Windows.Forms.DataGridView
    {
        #region Define Variable
        private int m_iGridHeight = 0;
        private int m_iColumnsWidthSum;
        private int m_iRowsPerPage;
        private string m_strColumnWidth = "";
        private string m_strColumnFormat = "";
        private DataTable m_dtDataGrid = null;
        private DataTable m_dtDataGridOld = null;
        private const int DEFAULT_ROWS_NUM = 20;
        private bool m_bIsPressShift = false;
        private SqlConnection m_CnCon;
        private string m_strConnectionString = "";
        private ComFunc dbCon = null;
        private string m_strConditionSql = "";
        private string m_strFirstSortColumn = string.Empty;
        private bool m_bIsEnterCellSelectRow = true;
        private bool m_bIsShowAsTree = false;
        private bool m_bIsExpand = false;
        private bool m_bIsSetFocus = true;
        private bool m_bIsAllowSort = true;
        private string m_strMenuVisible = string.Empty;
        private string m_strSort = string.Empty;
        private string[,] m_arrStrSort;
        private int m_iTreeLevel = 0;
        private bool m_bSetZeroValueToEmpty = false;

        public delegate void QueryDataEventHandler(object sender, EventArgs e);
        public event QueryDataEventHandler QueryData;
        protected virtual void OnQueryData(EventArgs e)
        {
            if (QueryData != null)
            {
                QueryData(this, e);
            }
        }

        public DataTable DataTable
        {
            get
            {
                return m_dtDataGrid;
            }
            set
            {
                Cursor curCurren = Cursor.Current;
                Cursor.Current = Cursors.WaitCursor;
                m_dtDataGridOld = m_dtDataGrid;
                m_dtDataGrid = value;
                SetMenu();
                if (m_dtDataGrid != null)
                {
                    ShowData(m_dtDataGrid);
                }
                Cursor.Current = curCurren;
            }
        }

        public int RowsPerPage
        {
            get
            {
                return m_iRowsPerPage;
            }
            set
            {
                m_iRowsPerPage = value;
            }
        }

        public int ColumnsWidthSum
        {
            get
            {
                return m_iColumnsWidthSum;
            }
            set
            {
                m_iColumnsWidthSum = value;
            }
        }

        [Description("Size of columns in pixel, splitted by ,"), RefreshProperties(RefreshProperties.All)]
        public string ColumnWidth
        {
            get
            {
                return m_strColumnWidth;
            }
            set
            {
                m_strColumnWidth = value;
				//SetAllColumnWidth(m_strColumnWidth);
            }
        }

        [Description("Set columns format style, splitted by ,"), RefreshProperties(RefreshProperties.All)]
        public string ColumnFormat
        {
            get
            {
                return m_strColumnFormat;
            }
            set
            {
                m_strColumnFormat = value;
            }
        }

        public string ConnectionString
        {
            get
            {
                return m_strConnectionString;
            }
            set
            {
                m_strConnectionString = value;
            }
        }

        public SqlConnection Con
        {
            get
            {
                return m_CnCon;
            }
            set
            {
                m_CnCon = value;
            }
        }

        [Description("Gets or sets the condition sql string")]
        public string ConditionSql
        {
            get
            {
                return m_strConditionSql;
            }
            set
            {
                m_strConditionSql = value;
                //if (m_strConditionSql != "")
                //    SetConditionSql(m_strConditionSql);
            }
        }

        public bool IsSetFocus
        {
            get
            {
                return m_bIsSetFocus;
            }
            set
            {
                m_bIsSetFocus = value;
            }
        }

        public bool EnterCellSelectRow
        {
            get
            {
                return m_bIsEnterCellSelectRow;
            }
            set
            {
                m_bIsEnterCellSelectRow = value;
            }
        }

        public bool IsShowAsTree
        {
            get
            {
                return m_bIsShowAsTree;
            }
            set
            {
                m_bIsShowAsTree = value;
            }
        }

        public bool IsAllowSort
        {
            get
            {
                return m_bIsAllowSort;
            }
            set
            {
                m_bIsAllowSort = value;
            }
        }

        public bool SetZeroValueToEmpty
        {
            get
            {
                return m_bSetZeroValueToEmpty;
            }
            set
            {
                m_bSetZeroValueToEmpty = value;
            }
        }

        [Description("Visible of right menu, '1' is visible, '0' is invisible, splitted by ','. Menu List: 1.Find; 2.Defined Column")]
        public string MenuVisibleString
        {
            get
            {
                return m_strMenuVisible;
            }
            set
            {
                m_strMenuVisible = value;
            }
        }

        [Description("Tree display with Level, 0: first level")]
        public int TreeLevel
        {
            get
            {
                return m_iTreeLevel;
            }
            set
            {
                m_iTreeLevel = value;
            }
        }
        #endregion

        #region Constructor Functions
        public DataGridCom()
        {
            InitializeComponent();
        }

        public DataGridCom(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }
        #endregion

        #region private Functions
        public bool ShowData(DataTable dt)
        {
            #region deal with data
            if (m_strConditionSql != "")
                dt.DefaultView.RowFilter = m_strConditionSql;
            else
                dt.DefaultView.RowFilter = string.Empty;
            #endregion

            if (dt != null)
            {
                //if (this.CurrentCell == null)
                //{
                //    this.CurrentCell = this[0,0];
                //}

                this.Refresh();

                //DBAccess dBAccess=new DBAccess(false,false);
                dbCon = new ComFunc();
                if (m_CnCon != null)
                    dbCon.ConnectionDB(m_CnCon);
                else
                    dbCon.ConnectionDB(m_strConnectionString);

                //Set PerPage Rows
                int iRowHeight = 16;

                if (m_iGridHeight == 0)
                    m_iGridHeight = GetGridHeight();
                m_iRowsPerPage = ((m_iGridHeight - 18) / iRowHeight) - 3; //18 is this.ColumnHeadersHeight
                if (m_iRowsPerPage < 0) m_iRowsPerPage = ((m_iGridHeight - 18) / iRowHeight);//16 is the rowheight


                if (m_iGridHeight <= 0) m_iRowsPerPage = DEFAULT_ROWS_NUM;

                if (m_dtDataGridOld != dt) //dataTable had been changed
                {
                    //this.DataSource = dt.DefaultView;
                    InitGridColumn(dt);
                    //SetAllColumnFormat();
                    m_dtDataGridOld = dt;
                }

                SetGridValue(dt);

                if (m_CnCon == null)
                    dbCon.CloseCon();

                ////this.SetSortGlyph();

                FormatData();

                if (this.ColumnWidth == "")
                {
                    //Use datagridview auto resize column
                    this.AutoResizeColumns();
                }
                SetAllColumnWidth(this.ColumnWidth);

                if (m_bIsShowAsTree)
                    ShowTree();

                this.OnQueryData(new EventArgs());
            }

            return true;
        }

        public bool ShowData()
        {
            Cursor curCurren = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;

            if (m_dtDataGrid != null)
            {
                ShowData(m_dtDataGrid);
            }
            Cursor.Current = curCurren;

            return true;
        }

        public bool ShowData(string SortString)
        {
            Cursor curCurren = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;
            string strSortColumn = string.Empty;
            string strSortDirection = string.Empty;

            if (m_dtDataGrid != null)
            {
                if (SortString != string.Empty)
                    m_dtDataGrid.DefaultView.Sort = SortString;

                ShowData(m_dtDataGrid);

                for (int i = 0; i < m_arrStrSort.GetLength(0); i++)
                {
                    strSortColumn = m_arrStrSort[i, 0].ToString().Replace("[", "").Replace("]", "");
                    if (strSortColumn.IndexOf('.') != -1)
                        strSortColumn = strSortColumn.Substring(strSortColumn.IndexOf('.') + 1);

                    strSortDirection = m_arrStrSort[i, 1] == null ? "ASC" : m_arrStrSort[i, 1].ToString().Trim().ToUpper();
                    this.Columns[strSortColumn].HeaderCell.SortGlyphDirection = strSortDirection == "DESC" ? System.Windows.Forms.SortOrder.Descending : System.Windows.Forms.SortOrder.Ascending;
                }
            }
            Cursor.Current = curCurren;

            return true;
        }

        private void SetAllColumnWidth(string ColumnWidth)
        {
            string[] ColumnWidthArray;
            int iScrollWidth = 0;

            if (this.VerticalScrollBar.Visible)
                iScrollWidth = 20;
            else
                iScrollWidth = 0;

            if (m_strColumnWidth != "")
            {
                this.ColumnsWidthSum = 0;
                ColumnWidthArray = m_strColumnWidth.Split(',');
                for (int i = 0; i < ColumnWidthArray.Length; i++)
                {
                    if (i >= this.Columns.Count) break;
                    this.Columns[i].Width = Convert.ToInt32(ColumnWidthArray[i]);
                    this.ColumnsWidthSum += Convert.ToInt32(ColumnWidthArray[i]);
                }

            }
            else
            {
                int iColumnsWidthSum = 0;

                for (int i = 0; i < this.Columns.Count; i++)
                {
                    if (this.Columns[i].Visible)
                        iColumnsWidthSum += this.Columns[i].Width;
                }

                if (this.RowHeadersWidth + iColumnsWidthSum + iScrollWidth < this.Width)
                    FillGridBlank(this.Width - this.RowHeadersWidth - iColumnsWidthSum - iScrollWidth);
            }
            if (m_bIsSetFocus)
                this.Focus();
        }

        public void FillGridBlank(int ColumnsWidthSum)
        {
            int iColumnCount = this.Columns.Count - 1;//subtract the hide column

            this.ColumnsWidthSum += ColumnsWidthSum;
            this.Columns[iColumnCount].Width += ColumnsWidthSum;
        }

        private void SetAllColumnFormat()
        {
            string[] strArrColumnFormat = null;

            if (m_strColumnFormat != "")
            {
                strArrColumnFormat = m_strColumnFormat.Split(',');

                for (int i = 0; i < strArrColumnFormat.Length; i++)
                {
                    if (strArrColumnFormat[i] != "")
                        this.Columns[i].DefaultCellStyle.Format = strArrColumnFormat[i];
                }
            }
        }

        private void InitGridColumn(DataTable dt)
        {
            DataGridViewTextBoxColumn dgcol = null;
            DataGridViewImageColumn dgImgCol = null;

            try
            {
                this.Columns.Clear();
            }
            catch
            {
            }

            for (int i = 0; i < dt.Columns.Count; i++)
            {
                if (m_bIsShowAsTree && i == 0)
                {
                    //if (dt.Columns[i].ColumnName.ToUpper() == "DESP")
                    //{
                    //    dgImgCol = new WP.Controls.GridColumn.TextImageColumn();
                    //    dgImgCol.Name = dt.Columns[i].ColumnName;
                    //}
                    dgImgCol = new DataGridViewImageColumn();
                    Bitmap bmPlus = new Bitmap(this.iglTree.Images["blank.ico"]);
                    dgImgCol.Image = bmPlus;
                    dgImgCol.Description = "ABC";
                    dgImgCol.Width = 40;
                    this.Columns.Add(dgImgCol);
                    this.Columns[0].Resizable = DataGridViewTriState.False;
                }

                dgcol = new DataGridViewTextBoxColumn();
                dgcol.Name = dt.Columns[i].ColumnName;
                if (dt.Columns[i].DataType.Name.ToUpper() == "DECIMAL")
                {
                    dgcol.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                }

                //if (m_bIsShowAsTree && dt.Columns[i].ColumnName.ToUpper() == "DESP")
                //    this.Columns.Add(dgImgCol);
                //else
                    this.Columns.Add(dgcol);
            }

            SetAllColumnFormat();
        }

        private void SetGridValue(DataTable dt)
        {
            int iRows;
            int iColIndex = 0;
            DataView dv = null;
            this.Rows.Clear();

            dv = dt.DefaultView;
            iRows = dv.Count;
            if (iRows > 0)
            {
                this.Rows.Add(iRows);

                for (int i = 0; i < iRows; i++)
                {
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        if (j == 0)
                        {
                            if (m_bIsShowAsTree)
                                iColIndex = 1;
                            else
                                iColIndex = 0;
                        }

                        if (dt.Columns[j].DataType.Name.ToUpper() == "BOOLEAN")
                        {
                            if (dv[i][j] != DBNull.Value)
                                this[iColIndex, i].Value = Convert.ToBoolean(dv[i][j].ToString());
                            else
                                this[iColIndex, i].Value = false;
                        }
                        else if (dt.Columns[j].DataType.Name.ToUpper() == "DECIMAL")
                        {
                            if (ComFunc.ToDouble(dv[i][j]) == 0 && m_bSetZeroValueToEmpty)
                                this[iColIndex, i].Value = null;
                            else if (dv[i][j].ToString() != "")
                                this[iColIndex, i].Value = Convert.ToDouble(dv[i][j].ToString());
                            else
                                this[iColIndex, i].Value = 0;
                        }
                        else if (dt.Columns[j].DataType.Name.ToUpper() == "INT32")
                        {
                            if (dv[i][j].ToString() != "")
                                this[iColIndex, i].Value = Convert.ToInt32(dv[i][j].ToString());
                            else
                                this[iColIndex, i].Value = 0;
                        }
                        else if (dt.Columns[j].DataType.Name.ToUpper() == "INT64")
                        {
                            if (dv[i][j].ToString() != "")
                                this[iColIndex, i].Value = Convert.ToInt64(dv[i][j].ToString());
                            else
                                this[iColIndex, i].Value = 0;
                        }
                        //else if (dt.Columns[j].DataType.Name.ToUpper() == "DATETIME")
                        //{
                        //    if (dv[i][j].ToString() != "")
                        //        this[iColIndex, i].Value = Convert.ToDateTime(dv[i][j].ToString());
                        //    else
                        //        this[iColIndex, i].Value = null;
                        //}
                        else
                            this[iColIndex, i].Value = dv[i][j].ToString();

                        iColIndex += 1;
                    }
                }
            }

        }

        private void FormatData()
        {
            int iColIndex = 0;
            DataColumn dc;

            if (this.Rows.Count > 0)
            {
                for (int i = 0; i < this.DataTable.Columns.Count; i++)
                {
                    if (i == 0 && m_bIsShowAsTree) iColIndex = i + 1;
                    dc = this.DataTable.Columns[i];
                    if (dc.DataType.Name.ToUpper() == "STRING")
                    {
                        for (int j = 0; j < this.DataTable.Rows.Count; j++)
                        {
                            if (j > this.Rows.Count - 1) break;
                            if (this[iColIndex, j].Value != null && this[dc.ColumnName, j].Value != null)
                                this[iColIndex, j].Value = this[dc.ColumnName, j].Value.ToString().TrimEnd();
                        }
                    }
                    else if (dc.DataType.Name.ToUpper() == "DATETIME")
                    {
                        for (int j = 0; j < this.DataTable.Rows.Count; j++)
                        {
                            if (j > this.Rows.Count - 1) break;
                            if (this[iColIndex, j].Value != null && this[dc.ColumnName, j].Value.ToString() != "")
                                this[iColIndex, j].Value = DateTime.Parse(this[dc.ColumnName, j].Value.ToString()).ToString("MM/dd/yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo);
                                //this[iColIndex, j].Value = Convert.ToDateTime(DateTime.Parse(this[dc.ColumnName, j].Value.ToString()).ToString("MM/dd/yyyy", System.Globalization.DateTimeFormatInfo.InvariantInfo)).Date;
                        }
                    }
                    else if (dc.DataType.Name.ToUpper() == "BOOLEAN")
                    {
                        for (int j = 0; j < this.DataTable.Rows.Count; j++)
                        {
                            if (j > this.Rows.Count - 1) break;
                            if (this[iColIndex, j].Value != null)
                            {
                                this[iColIndex, j].Value = this[dc.ColumnName, j].Value.ToString() == "True" ? "Yes" : "No";
                            }
                        }
                    }

                    iColIndex += 1;
                }
            }
        }

        private int GetGridHeight()
        {
            //dgList.Parent.GetType().Name == TabControl  
            int iFormHeight = 0;
            ArrayList conArr = new ArrayList(5);
            Control conParent1 = null, conParent2 = null, conParent3 = null, conParent4 = null, conParent5 = null;
            string strFormName = this.FindForm().Name;
            conParent1 = this.Parent;
            conArr.Add(conParent1);
            if (conParent1 != null && conParent1.Parent != null && conParent1.Parent.Name != strFormName)
            {
                conParent2 = conParent1.Parent;
                conArr.Add(conParent2);
            }
            if (conParent2 != null && conParent2.Parent != null && conParent2.Parent.Name != strFormName)
            {
                conParent3 = conParent2.Parent;
                conArr.Add(conParent3);
            }
            if (conParent3 != null && conParent3.Parent != null && conParent3.Parent.Name != strFormName)
            {
                conParent4 = conParent3.Parent;
                conArr.Add(conParent4);
            }
            if (conParent4 != null && conParent4.Parent != null && conParent4.Parent.Name != strFormName)
            {
                conParent5 = conParent4.Parent;
                conArr.Add(conParent5);
            }
            conArr.TrimToSize();

            foreach (Control con in conArr)
            {
                switch (con.GetType().Name)
                {
                    case "TabPage":
                        break;
                    case "TabControl":
                        TabControl tabcon = con as TabControl;
                        iFormHeight -= tabcon.Top + tabcon.ItemSize.Height + 8;
                        break;
                    default:
                        if (con.Name != strFormName && con.GetType().Name != "MdiClient" && con.Name != "frmMain") iFormHeight -= con.Top;
                        break;
                }
                if (con.Parent != null && con.Parent.Name == strFormName)
                {
                    iFormHeight += con.Parent.Height;
                }
                else if (con.Name == strFormName)
                {
                    iFormHeight += con.Height;
                }
            }
            return iFormHeight;
        }

        public void FindRecord(string FindValue, string FindField)
        {
            string strColumn = string.Empty;
            if (m_strConditionSql != "")
                this.CurrentCell = this[0, 0];
            else
            {
                for (int i = 0; i < this.Rows.Count; i++)
                {
                    if (string.Compare(this[FindField, i].Value.ToString(),FindValue, true) == 0 ||
                        this[FindField, i].Value.ToString().ToUpper().IndexOf(FindValue.ToUpper()) != -1)
                    {
                        strColumn = GetFirstVisibleColumn();
                        strColumn = strColumn.TrimStart('[').TrimEnd(']');
                        this.CurrentCell = this[strColumn, i];
                        break;
                    }
                }
            }
        }

        private string GetFirstVisibleColumn()
        {
            for (int i = 0; i < this.Columns.Count; i++)
            {
                if (this.Columns[i].Visible)
                    return "[" + this.Columns[i].Name.ToUpper() + "]";
            }

            return "";
        }

        private void ShowFindForm(string SortColumn, string SortColumnTitle, string SortDirection)
        {
            frmFind FrmFind = new frmFind();
            FrmFind.ShowFindForm(string.Empty, SortColumn, SortColumnTitle, SortDirection, m_CnCon, m_strConnectionString, null, this);
            ////FrmFind.TableName = m_strTableName;
            //FrmFind.SortColumn = SortColumn;
            //FrmFind.SortColumnTitle = SortColumnTitle;
            //FrmFind.SortDirection = SortDirection;
            //FrmFind.DataGridCom = this;

            //dbCon = new ComFunc();
            //if (m_CnCon != null)
            //    dbCon.ConnectionDB(m_CnCon);
            //else
            //    dbCon.ConnectionDB(m_strConnectionString);

            //FrmFind.DBCon = dbCon;
            //FrmFind.ShowDialog();

            if (m_CnCon == null)
                dbCon.CloseCon();
        }

        private void ShowTree()
        {
            string strKeyNo = string.Empty;
            int iLevel = 0;
            int iNextLevel = 0;
            DataView dv = null;
            int iShowLevel = 0;

            iShowLevel = m_iTreeLevel;
            dv = m_dtDataGrid.DefaultView;
            for (int i = 0; i < this.Rows.Count; i++)
            {
                iLevel = this["mylevel", i].Value == null || this["mylevel", i].Value.ToString() == "" ? 0 : Convert.ToInt32(this["mylevel", i].Value.ToString());
                if (iLevel > iShowLevel)
                    this.Rows[i].Visible = false;
                else
                {
                    #region set row image
                    strKeyNo = this["PlnNo", i].Value.ToString();
                    iNextLevel = iLevel + 1;
                    dv.RowFilter = "PlnNo like '%" + strKeyNo + "%' and mylevel = " + iNextLevel;
                    if (dv.Count > 0)
                        this[0, i].Value = this.iglTree.Images["plus.ico"];
                    else
                        this[0, i].Value = null;
                    #endregion
                }
            }
        }

        private void SetMenu()
        {
            string[] arrVisible = null;
            tmiNew.Visible = false;
            tmiUpdate.Visible = false;
            tmiDelete.Visible = false;

            if (m_strMenuVisible == string.Empty || m_strMenuVisible.Split(',').Length < 1)
                m_strMenuVisible = "1";

            arrVisible = m_strMenuVisible.Split(',');
            tmiFind.Visible = (arrVisible[0] == "1" ? true : false);
            if (!m_bIsAllowSort) { tmiFind.Visible = false; }
        }
        #endregion

        #region private Events
        public void miFind_Click(object sender, System.EventArgs e)
        {
            string strSortColumnTitle = "";
            string strSortDirection = "ASC";

            if (!m_bIsAllowSort) return;
            if (this.Columns.Count > 0)
            {
                for (int i =0; i< this.Columns.Count; i++)
                {
                    if (this.Columns[i].HeaderCell.SortGlyphDirection != System.Windows.Forms.SortOrder.None)
                    {
                        m_strFirstSortColumn = "[" + this.Columns[i].Name.ToUpper() + "]";
                        strSortDirection = this.Columns[i].HeaderCell.SortGlyphDirection == System.Windows.Forms.SortOrder.Descending ? "DESC" : "ASC";
                        break;
                    }
                }

                if (m_strFirstSortColumn == "" || m_strFirstSortColumn.ToUpper() == "[RECID]")
                {
                    m_strFirstSortColumn = GetFirstVisibleColumn();
                }
                else
                {
                }

                if (m_strFirstSortColumn != "")
                {
                    strSortColumnTitle = this.Columns[m_strFirstSortColumn.Replace("[", "").Replace("]", "")].HeaderText;
                    ShowFindForm(m_strFirstSortColumn, strSortColumnTitle, strSortDirection);
                }
            }
        }

        protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
        {
            //string strSort = string.Empty;
            //if (m_bIsAllowSort && this.Columns[e.ColumnIndex].Name.Trim() != string.Empty)
            //{
            //    this.ConditionSql = "";

            //    for (int i = 0; i < this.Columns.Count; i++)
            //    {
            //        if (this.Columns[i].HeaderCell.SortGlyphDirection != System.Windows.Forms.SortOrder.None)
            //        {
            //            m_strFirstSortColumn = this.Columns[i].Name;
            //            break;
            //        }
            //    }

            //    if (this.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection != System.Windows.Forms.SortOrder.Ascending)
            //    {
            //        strSort = "[" + this.Columns[e.ColumnIndex].Name + "]" + " ASC";
            //        if (this.Columns[e.ColumnIndex].SortMode != DataGridViewColumnSortMode.NotSortable)
            //            this.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = System.Windows.Forms.SortOrder.Ascending;
            //    }
            //    else
            //    {
            //        strSort = "[" + this.Columns[e.ColumnIndex].Name + "]" + " DESC";
            //        if (this.Columns[e.ColumnIndex].SortMode != DataGridViewColumnSortMode.NotSortable)
            //            this.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = System.Windows.Forms.SortOrder.Descending;
            //    }
            //    if (m_strFirstSortColumn != string.Empty && m_strFirstSortColumn != this.Columns[e.ColumnIndex].Name)
            //        this.Columns[m_strFirstSortColumn].HeaderCell.SortGlyphDirection = System.Windows.Forms.SortOrder.None;
            //    this.ShowData(strSort);
            //    //base.OnColumnHeaderMouseClick(e);
            //}

            if (!m_bIsAllowSort) return;

            string strGridColumnName = ""; //the column name that bind the grid (not include table name)
            string[] arrStrColumnAndDirection;
            bool bSortColumnChanged = false;
            string[,] arrStrSortOld = null;

            if (m_arrStrSort != null)
            {
                arrStrSortOld = new string[m_arrStrSort.GetLength(0), m_arrStrSort.GetLength(1)];
                arrStrSortOld = (string[,])m_arrStrSort.Clone();
            }

            this.ConditionSql = "";

            #region init Sort Array, Add new column
            arrStrColumnAndDirection = m_strSort.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            if (arrStrColumnAndDirection.Length > 0 && m_bIsPressShift)
            {
                if (m_strSort.IndexOf("[" + this.Columns[e.ColumnIndex].Name + "]", StringComparison.CurrentCultureIgnoreCase) == -1)
                {
                    m_arrStrSort = new string[arrStrColumnAndDirection.Length + 1, 2]; // create n+1 for new column
                    m_arrStrSort[arrStrColumnAndDirection.Length, 0] = string.Empty;
                    m_arrStrSort[arrStrColumnAndDirection.Length, 1] = "ASC";
                }

                for (int i = 0; i < arrStrColumnAndDirection.Length; i++)
                {
                    m_arrStrSort[i, 0] = arrStrColumnAndDirection[i].Split(' ')[0].Trim(); // Sort column
                    m_arrStrSort[i, 1] = arrStrColumnAndDirection[i].Split(' ')[1].Trim() == string.Empty ? "ASC" : arrStrColumnAndDirection[i].Split(' ')[1].Trim(); // Sort direction
                }
            }
            else
            {
                m_arrStrSort = new string[1, 2] { { string.Empty, "ASC" } };
            }
            #endregion

            #region set new sort column name
            if (m_bIsPressShift)
            {
                if (m_strSort.IndexOf("[" + this.Columns[e.ColumnIndex].Name + "]", StringComparison.CurrentCultureIgnoreCase) == -1)
                {
                    bSortColumnChanged = true;
                    if (arrStrColumnAndDirection.Length == 0)
                        m_arrStrSort[0, 0] = this.Columns[e.ColumnIndex].Name;
                    else
                        m_arrStrSort[arrStrColumnAndDirection.Length, 0] = "[" + this.Columns[e.ColumnIndex].Name + "]";
                }
            }
            else
            {
                if (arrStrSortOld == null || (arrStrSortOld != null && arrStrSortOld[0, 0] != this.Columns[e.ColumnIndex].Name))
                { 
                    bSortColumnChanged = true;
                    m_arrStrSort[0, 0] = this.Columns[e.ColumnIndex].Name;
                }
            }
            #endregion

            #region set new sort direction
            if (bSortColumnChanged)
            {
                //get rid of the old sort photograph
                if (arrStrSortOld != null)
                {
                    for (int j = 0; j < arrStrSortOld.GetLength(0); j++)
                    {
                        strGridColumnName = arrStrSortOld[j, 0].ToString().Replace("[", "").Replace("]", "");
                        if (strGridColumnName.IndexOf('.') != -1)
                            strGridColumnName = strGridColumnName.Substring(strGridColumnName.IndexOf('.') + 1);
                        this.Columns[strGridColumnName].HeaderCell.SortGlyphDirection = System.Windows.Forms.SortOrder.None;
                    }
                }
            }
            else
            {
                if (m_bIsPressShift)
                {
                    for (int k = 0; k < m_arrStrSort.GetLength(0); k++)
                    {
                        if (m_arrStrSort[k,0].ToString() == "[" + this.Columns[e.ColumnIndex].Name + "]")
                        {
                            if (m_arrStrSort[k,1].ToString().Trim().ToUpper() != "DESC")
                                m_arrStrSort[k,1] = "DESC";
                            else
                                m_arrStrSort[k,1] = "ASC";
                            break;
                        }
                    }

                }
                else
                {
                    m_arrStrSort[0, 0] = this.Columns[e.ColumnIndex].Name;
                    if (arrStrSortOld[0, 1] != "DESC")
                        m_arrStrSort[0, 1] = "DESC";
                    else
                        m_arrStrSort[0, 1] = "ASC";
                }
            }
            #endregion

            #region get sort string
            m_strSort = string.Empty;
            for (int m = 0; m < m_arrStrSort.GetLength(0); m++)
            {
                if (m_arrStrSort[m, 0] == null) { continue; }
                m_strSort += m_arrStrSort[m, 0].IndexOf('[') == -1 ? "[" + m_arrStrSort[m, 0] + "]" : m_arrStrSort[m, 0];
                if (m_arrStrSort[m, 1] == null || m_arrStrSort[m, 1] == string.Empty)
                    m_strSort += " ASC,";
                else
                    m_strSort += " " + m_arrStrSort[m, 1].ToString() + ",";
            }
            m_strSort = m_strSort.TrimEnd(',');
            #endregion

            this.ShowData(m_strSort);

        }

        private void DataGridCom_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (this.CurrentCell != null)
            {
                if (!this.CurrentRow.Selected)
                    this.CurrentRow.Selected = true;
            }
        }

        private void DataGridCom_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (m_bIsEnterCellSelectRow)
                this.CurrentRow.Selected = true;
        }

        private void DataGridCom_CellClick(object sender, System.Windows.Forms.DataGridViewCellEventArgs e)
        {
            string strKeyNo = string.Empty;
            string[] arrKeyNo = new string[9];
            string[] arrCurRowKeyNo = new string[9];
            int iLevel = 0;
            int iNextLevel = 0;
            int iCurRowLevel = 0;
            bool bIsChild = true;

            if (e.RowIndex == -1) return;
            if (m_bIsShowAsTree)
            {
                if (this["PlnNo", e.RowIndex].Value != null && this["mylevel", e.RowIndex].Value != null)
                {
                    strKeyNo = this["PlnNo", e.RowIndex].Value.ToString();
                    arrKeyNo = strKeyNo.Split('@');
                    iLevel = this["mylevel", e.RowIndex].Value.ToString() == "" ? 0 : Convert.ToInt32(this["mylevel", e.RowIndex].Value.ToString());
                    iNextLevel = iLevel + 1;
                    DataView dv = m_dtDataGrid.DefaultView;
                    dv.RowFilter = "PlnNo like '%" + strKeyNo + "%' and mylevel = " + iNextLevel;
                    if (dv.Count > 0) //if it has child
                    {
                        if (this["isleaf", e.RowIndex].Value.ToString().ToUpper() == "YES" ? true : false)
                        {
                            for (int i = 0; i < m_dtDataGrid.Rows.Count; i++)
                            {
                                bIsChild = true;
                                iCurRowLevel = this["mylevel", i].Value.ToString() == "" ? 0 : Convert.ToInt32(this["mylevel", i].Value.ToString());
                                if (this["PlnNo", i].Value != null && iCurRowLevel >= iNextLevel)
                                {
                                    //this.CurrentCell = null;
                                    arrCurRowKeyNo = this["PlnNo", i].Value.ToString().Split('@');
                                    for (int j = 0; j < arrKeyNo.Length; j++)
                                    {
                                        if (arrKeyNo[j].TrimEnd() != arrCurRowKeyNo[j].TrimEnd())
                                        {
                                            bIsChild = false;
                                            break;
                                        }
                                    }
                                    if (!bIsChild)
                                        continue;

                                    this.Rows[i].Visible = false;
                                    this["isleaf", i].Value = false;
                                }
                            }
                            this["isleaf", e.RowIndex].Value = "No";
                            this[0, e.RowIndex].Value = this.iglTree.Images["plus.ico"];
                        }
                        else
                        {
                            for (int i = 0; i < m_dtDataGrid.Rows.Count; i++)
                            {
                                iCurRowLevel = this["mylevel", i].Value.ToString() == "" ? 0 : Convert.ToInt32(this["mylevel", i].Value.ToString());
                                if (this["PlnNo", i].Value != null && iCurRowLevel == iNextLevel)
                                {
                                    bIsChild = true;
                                    arrCurRowKeyNo = this["PlnNo", i].Value.ToString().Split('@');
                                    for (int j = 0; j < arrKeyNo.Length; j++)
                                    {
                                        if (arrKeyNo[j].TrimEnd() != arrCurRowKeyNo[j].TrimEnd())
                                        {
                                            bIsChild = false;
                                            break;
                                        }
                                    }
                                    if (!bIsChild)
                                        continue;

                                    this.Rows[i].Visible = true;
                                    #region set expand row image
                                    dv.RowFilter = "PlnNo like '%" + this["PlnNo", i].Value.ToString() + "%' and mylevel = " + Convert.ToString(iNextLevel + 1);
                                    if (dv.Count > 0)
                                        this[0, i].Value = this.iglTree.Images["plus.ico"];
                                    else
                                        this[0, i].Value = null;
                                    #endregion
                                }
                            }
                            this["isleaf", e.RowIndex].Value = "Yes";
                            this[0, e.RowIndex].Value = this.iglTree.Images["minus.ico"];
                        }
                    }
                }
            }

        }

        private void DataGridCom_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            return;
        }

        private void DataGridCom_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ShiftKey)
                m_bIsPressShift = false;
        }

        private void DataGridCom_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ShiftKey)
                m_bIsPressShift = true;
        }

        //protected override void OnRowEnter(DataGridViewCellEventArgs e)
        //{
        //    if (!this.m_CnCon)
        //        base.OnRowEnter(e);
        //}
        #endregion
    }
}
